package com.cnpc.framework.base.service.impl;

import com.alibaba.fastjson.JSON;
import com.cnpc.framework.base.entity.Dict;
import com.cnpc.framework.base.pojo.Result;
import com.cnpc.framework.base.pojo.TreeNode;
import com.cnpc.framework.base.service.DictService;
import com.cnpc.framework.constant.RedisConstant;
import com.cnpc.framework.utils.StrUtil;
import com.cnpc.framework.utils.TreeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.awt.event.ActionEvent;
import java.util.*;

@Service("dictService")
public class DictServiceImpl extends BaseServiceImpl implements DictService {

    @Override
    public List<TreeNode> getTreeData(String code) {

        // 获取数据
        String key = RedisConstant.DICT_PRE + "tree";
        List<TreeNode> tnlist = null;
        String tnStr = redisDao.get(key);
        if (!StrUtil.isEmpty(tnStr) && StrUtil.isEmpty(code)) {
            tnlist = JSON.parseArray(tnStr, TreeNode.class);
        }
        if (tnlist != null) {
            return tnlist;
        } else if(StringUtils.isEmpty(code)){
            String hql = "from Dict order by levelCode asc";
            List<Dict> dicts = this.find(hql);
            Map<String, TreeNode> nodelist = new LinkedHashMap<String, TreeNode>();
            for (Dict dict : dicts) {
                TreeNode node = new TreeNode();
                node.setText(dict.getName());
                node.setId(dict.getId());
                node.setCode(dict.getCode());
                node.setParentId(dict.getParentId());
                node.setLevelCode(dict.getLevelCode());
                node.setValue(dict.getValue());
                node.setDeleted(dict.getDeleted());
                nodelist.put(node.getId(), node);
            }
            // 构造树形结构
            tnlist = TreeUtil.getNodeList(nodelist);
            if (StrUtil.isEmpty(code)) {
                redisDao.save(key, tnlist);
            }
            return tnlist;
        }else {
            String sql = "select * from tbl_dict where code = :code";
            Map<String, Object> params = new HashMap<>();
            params.put("code", code);
            Dict root = getBySql(sql, params,Dict.class);
            if (root == null) {
                return null;
            }

            sql = "select * from tbl_dict where levelCode like :code order by levelCode asc";
            params.put("code", root.getLevelCode()+"0%");
            List<Dict> dicts = findBySql(sql,params,Dict.class);

            if (dicts == null) {
                dicts = new ArrayList<>();
            }
            root.setParentId(null);
            dicts.add(0,root);
            Map<String, TreeNode> nodelist = new LinkedHashMap<String, TreeNode>();
            for (Dict dict : dicts) {
                TreeNode node = new TreeNode();
                node.setText(dict.getName());
                node.setId(dict.getId());
                node.setCode(dict.getCode());
                node.setParentId(dict.getParentId());
                node.setLevelCode(dict.getLevelCode());
                node.setValue(dict.getValue());
                node.setDeleted(dict.getDeleted());
                nodelist.put(node.getId(), node);
            }
            // 构造树形结构
            tnlist = TreeUtil.getNodeList(nodelist);
            if (StrUtil.isEmpty(code)) {
                redisDao.save(key, tnlist);
            }
            return tnlist;
        }
    }

    public List<Dict> getDictsByCode(String code) {
        String key = RedisConstant.DICT_PRE + code;
        List dicts = redisDao.get(key, List.class);
        if (dicts == null) {
            String hql = "from Dict where code='" + code + "' and (deleted = 0 or deleted is null)";
            Dict dict = this.get(hql);
            if (dict == null) {
                return null;
            }
            dicts = this.find("from Dict where parentId='" + dict.getId() + "' and (deleted = 0 or deleted is null)  order by levelCode");
            redisDao.add(key, dicts);
            return dicts;
        } else {
            return dicts;
        }

    }

    @Override
    public Result editDict(Dict dict) throws Exception {
        String id = dict.getId();

        if (StringUtils.isEmpty(id)) {
            String sql = "select count(*) from tbl_dict where code ='" + dict.getCode() + "'";
            Long cnt = countBySql(sql);
            if (cnt > 0) {
                return new Result(false, "编码已存在");
            }
            if (StrUtil.isEmpty(dict.getParentId())) {
                sql = "select max(levelCode) from tbl_dict where parent_id is null or parent_id = ''";
                String tem = getBySql(sql);
                int value = 0;
                if (StringUtils.isNotEmpty(tem)) {
                    value = Integer.parseInt(tem);
                }
                value++;
                String levelCode = String.format("%06d", value);
                dict.setLevelCode(levelCode);
            } else {
                sql = "select max(levelCode) from tbl_dict where parent_id = '" + dict.getParentId() + "'";
                String tem = getBySql(sql);
                int value = 0;
                String prefix = "";
                if (StringUtils.isEmpty(tem)) {
                    sql = "select levelCode from tbl_dict where id = '" + dict.getParentId() + "'";
                    prefix = getBySql(sql);
                } else {
                    prefix = tem.substring(0, tem.length() - 6);
                    value = Integer.parseInt(tem.substring(tem.length() - 6));
                }
                value++;
                dict.setLevelCode(prefix + String.format("%06d", value));
            }
        } else {
            Dict oldDict = get(Dict.class, id);
            if (!oldDict.getCode().equals(dict.getCode())) {
                String sql = "select count(*) from tbl_dict where code ='" + dict.getCode() + "' and id <> '" + id + "'";
                Long cnt = countBySql(sql);
                if (cnt > 0) {
                    return new Result(false, "编码已存在");
                }
            }

            if (StringUtils.isNotEmpty(oldDict.getParentId()) && !oldDict.getParentId().equals(dict.getParentId()) ||
                    StringUtils.isNotEmpty(dict.getParentId()) && !dict.getParentId().equals(oldDict.getParentId())) {
                String sql;
                String levelCode = null;
                if (StrUtil.isEmpty(dict.getParentId())) {
                    sql = "select max(levelCode) from tbl_dict where parent_id is null or parent_id = ''";
                    String tem = getBySql(sql);
                    int value = 0;
                    if (StringUtils.isNotEmpty(tem)) {
                        value = Integer.parseInt(tem);
                    }
                    value++;
                    levelCode = String.format("%06d", value);
                } else {
                    sql = "select max(levelCode) from tbl_dict where parent_id = '" + dict.getParentId() + "'";
                    String tem = getBySql(sql);
                    int value = 0;
                    String prefix = "";
                    if (StringUtils.isEmpty(tem)) {
                        sql = "select levelCode from tbl_dict where id = '" + dict.getParentId() + "'";
                        prefix = getBySql(sql);
                    } else {
                        prefix = tem.substring(0, tem.length() - 6);
                        value = Integer.parseInt(tem.substring(tem.length() - 6));
                    }
                    value++;
                    levelCode = prefix + String.format("%06d", value);
                }
                dict.setLevelCode(levelCode);

                sql = "update tbl_dict set levelCode = concat(:preFix,substr(levelCode,:ut)) where levelCode like :levelCode";
                Map<String, Object> params = new HashMap<>();
                params.put("levelCode", oldDict.getLevelCode()+"0%");
                params.put("preFix", levelCode);
                params.put("ut", oldDict.getLevelCode().length()+1);
                executeSql(sql,params);
            }
            BeanUtils.copyProperties(dict, oldDict, "version", "create_date_time", "levelCode");
            dict = oldDict;
        }

        dict.setUpdateDateTime(new Date());
        saveOrUpdate(dict);
        String parentCode = "";
        if (!StrUtil.isEmpty(dict.getParentId())) {
            Dict parent = get(Dict.class, dict.getParentId());
            parentCode = parent.getCode();
            deleteCacheByKey(RedisConstant.DICT_PRE + parentCode);

        }
        deleteCacheByKey(RedisConstant.DICT_PRE + "tree");

        return new Result(true);
    }
}
